/*
 * This file will give a test to all functions of original
 * code left by Benjun Ying.
 * calling
 */

#include "tools.h"
#include <glog/logging.h>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "json.hpp"
#include "exudate_extract.h"
#include "vessel_extract.h"

#include "common.h"

using google::INFO;
using google::WARNING;
using google::FATAL;
using google::ERROR;
using boost::filesystem::path;
using boost::filesystem::exists;
using std::ifstream;
using std::ofstream;
using std::ios;
using std::cout;
using boost::filesystem::create_directory;
using boost::filesystem::is_directory;
using json = nlohmann::json;
using std::endl;

DEFINE_string(imglist,
              "/home/d/workspace/DeepDR/data/newdata/img/datadesp.json",
              "The image list in csv format");
DEFINE_string(fileout,
              "./segment_result/",
              "The image list in csv format");

Mat getMask(Mat _img, double thresh = 0.0001);


int main(int argc, char **argv) {
    srand((unsigned int) time(NULL));
    google::SetCommandLineOption("alsologtostderr", "true");
    google::SetCommandLineOption("colorlogtostderr", "true");
    google::InitGoogleLogging(argv[0]);
    google::SetUsageMessage(
            "Convert the original image set to lmdb database\n"
    );
    google::ParseCommandLineFlags(&argc, &argv, true);

    string filelist = FLAGS_imglist;
    string outputfolder = FLAGS_fileout;

    CHECK_EQ(exists(path(filelist)), true)
        << "No files are provided";
    if (!is_directory(path(outputfolder))) {
        CHECK_EQ(create_directory(path(outputfolder)), true)
            << "Cannot create directory"
            << outputfolder;
    }
    LOG(INFO) << path(filelist).parent_path();

    ifstream fin(filelist);
    string filelistContent((std::istreambuf_iterator<char>(fin)),
                           std::istreambuf_iterator<char>());

    auto imglist = json::parse(filelistContent);

    for (int i = 0; i < imglist.size(); i++) {
        string imagepath = (path(filelist).parent_path() / imglist[i]["original_image"]).string();
        LOG(INFO) << "handling " << imagepath;
        Mat oriimg = imread(imagepath);
        CHECK_EQ(oriimg.empty(), false) << "Error read image file";
        Mat mask = getMask(oriimg);
        Mat exclude = ori::exudate_extract(oriimg, mask);
        imglist[i]["exclude_image"] = imglist[i]["original_image"].get<string>() + string("_exclude");
        imwrite(outputfolder + imglist[i]["exclude_image"].get<string>(), exclude);
    }

    return 0;
}


Mat getMask(Mat _img, double thresh) {
    Mat img;
    _img.convertTo(img, CV_32FC(_img.channels()), 1.0 / 255.0);
    vector<Mat> image_channels;
    split(img, image_channels);
    Mat rChannel(img.rows, img.cols, CV_32FC1, Scalar(0));
    for (int i = 1; i < 2; i++) {
        rChannel += image_channels[i].mul(image_channels[i]);
    }
    double maxValue, minValue;
    minMaxLoc(rChannel, &minValue, &maxValue);
    return rChannel > thresh * maxValue;
//    result.setImage(rChannel > thresh * maxValue);
//    CHECK(!result.getOriginal().empty());
//    CHECK_EQ(CV_8U, result.getOriginal().depth());
//    CHECK_EQ(1, result.getOriginal().channels());
//    return result;
}
